.\"
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for
.\" permission to reproduce portions of its copyrighted documentation.
.\" Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
.\"
.\" The Institute of Electrical and Electronics Engineers and The Open
.\" Group, have given us permission to reprint portions of their
.\" documentation.
.\"
.\" In the following statement, the phrase ``this text'' refers to portions
.\" of the system documentation.
.\"
.\" Portions of this text are reprinted and reproduced in electronic form
.\" in the SunOS Reference Manual, from IEEE Std 1003.1, 2004 Edition,
.\" Standard for Information Technology -- Portable Operating System
.\" Interface (POSIX), The Open Group Base Specifications Issue 6,
.\" Copyright (C) 2001-2004 by the Institute of Electrical and Electronics
.\" Engineers, Inc and The Open Group.  In the event of any discrepancy
.\" between these versions and the original IEEE and The Open Group
.\" Standard, the original IEEE and The Open Group Standard is the referee
.\" document.  The original Standard can be obtained online at
.\" http://www.opengroup.org/unix/online.html.
.\"
.\" This notice shall appear on any product containing this material.
.\"
.\" The contents of this file are subject to the terms of the
.\" Common Development and Distribution License (the "License").
.\" You may not use this file except in compliance with the License.
.\"
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
.\" or http://www.opensolaris.org/os/licensing.
.\" See the License for the specific language governing permissions
.\" and limitations under the License.
.\"
.\" When distributing Covered Code, include this CDDL HEADER in each
.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
.\" If applicable, add the following below this CDDL HEADER, with the
.\" fields enclosed by brackets "[]" replaced with your own identifying
.\" information: Portions Copyright [yyyy] [name of copyright owner]
.\"
.\"
.\" Copyright 1989 AT&T
.\" Copyright 1992, X/Open Company Limited All Rights Reserved
.\" Portions Copyright (c) 1982-2007 AT&T Knowledge Ventures
.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved
.\"
.TH TEST 1 "Aug 11, 2009"
.SH NAME
test \- evaluate condition(s)
.SH SYNOPSIS
.LP
.nf
\fB/usr/bin/test\fR [\fIcondition\fR]
.fi

.LP
.nf
\fB[\fR [\fIcondition\fR] ]
.fi

.SS "sh"
.LP
.nf
\fBtest\fR [\fIcondition\fR]
.fi

.LP
.nf
\fB[\fR [\fIcondition\fR] ]
.fi

.SS "csh"
.LP
.nf
\fBtest\fR [\fIcondition\fR]
.fi

.LP
.nf
\fB[\fR [\fIcondition\fR] ]
.fi

.SS "ksh"
.LP
.nf
\fBtest\fR [\fIcondition\fR]
.fi

.LP
.nf
\fB[\fR [\fIcondition\fR] ]
.fi

.SS "ksh93"
.LP
.nf
\fBtest\fR [\fIcondition\fR]
.fi

.LP
.nf
\fB[\fR [\fIcondition\fR] ]
.fi

.SH DESCRIPTION
.sp
.LP
The \fBtest\fR utility evaluates the \fIcondition\fR and indicates the result
of the evaluation by its exit status. An exit status of zero indicates that the
condition evaluated as true and an exit status of 1 indicates that the
condition evaluated as false.
.sp
.LP
In the first form of the utility shown using the SYNOPSIS:
.sp
.in +2
.nf
test [\fIcondition\fR]
.fi
.in -2
.sp

.sp
.LP
the square brackets denote that \fIcondition\fR is an optional operand and are
not to be entered on the command line.
.sp
.LP
In the second form of the utility shown using the SYNOPSIS:
.sp
.in +2
.nf
\fB[\fR [ \fIcondition\fR ] \fB]\fR
.fi
.in -2
.sp

.sp
.LP
the first open square bracket, \fB[\fR, is the required utility name.
\fIcondition\fR is optional, as denoted by the inner pair of square brackets.
The final close square bracket, \fB]\fR, is a required operand.
.sp
.LP
See \fBlargefile\fR(7) for the description of the behavior of \fBtest\fR when
encountering files greater than or equal to 2 Gbyte (2^31 bytes).
.sp
.LP
The \fBtest\fR and \fB[\fR utilities evaluate the condition \fIcondition\fR
and, if its value is true, set exit status to \fB0\fR. Otherwise, a non-zero
(false) exit status is set. \fBtest\fR and \fB[\fR also set a non-zero exit
status if there are no arguments. When permissions are tested, the effective
user \fBID\fR of the process is used.
.sp
.LP
All operators, flags, and brackets (brackets used as shown in the last SYNOPSIS
line) must be separate arguments to these commands. Normally these arguments
are separated by spaces.
.SH OPERANDS
.sp
.LP
The primaries listed below with two elements of the form:
.sp
.in +2
.nf
\fI-primary_operator primary_operand\fR
.fi
.in -2

.sp
.LP
are known as \fBunary primaries\fR. The primaries with three elements in either
of the two forms:
.sp
.in +2
.nf
\fIprimary_operand -primary_operator primary_operand
primary_operand primary_operator primary_operand\fR
.fi
.in -2

.sp
.LP
are known as \fBbinary primaries\fR.
.sp
.LP
If any file operands except for \fB-h\fR and \fB-L\fR primaries refer to
symbolic links, the symbolic link is expanded and the test is performed on the
resulting file.
.sp
.LP
If you test a file you own (the \fB-r\fR \fB-w\fR or \fB-x\fR tests), but the
permission tested does not have the \fIowner\fR bit set, a non-zero (false)
exit status is returned even though the file can have the \fBgroup\fR or
\fBother\fR bit set for that permission.
.sp
.LP
The \fB=\fR and \fB!=\fR primaries have a higher precedence than the unary
primaries. The \fB=\fR and \fB!=\fR primaries always expect arguments;
therefore, \fB=\fR and \fB!=\fR cannot be used as an argument to the unary
primaries.
.sp
.LP
The following primaries can be used to construct \fIcondition\fR:
.sp
.ne 2
.na
\fB\fB-a\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists. (Not available in \fBsh\fR.)
.RE

.sp
.ne 2
.na
\fB\fB-b\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is a block special file.
.RE

.sp
.ne 2
.na
\fB\fB-c\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is a character special file.
.RE

.sp
.ne 2
.na
\fB\fB-d\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is a directory.
.RE

.sp
.ne 2
.na
\fB\fB-e\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists. (Not available in \fBsh\fR.)
.RE

.sp
.ne 2
.na
\fB\fB-f\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is a regular file. Alternatively, if
\fB/usr/bin/sh\fR users specify \fB/usr/ucb\fR before \fB/usr/bin\fR in their
\fBPATH\fR environment variable, then \fBtest\fR returns true if \fIfile\fR
exists and is (\fBnot\(mia\(midirectory\fR). The \fBcsh\fR \fBtest\fR and
\fB[\fR built-ins always use this alternative behavior.
.RE

.sp
.ne 2
.na
\fB\fB-g\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and its set group \fBID\fR flag is set.
.RE

.sp
.ne 2
.na
\fB\fB-G\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and its group matches the effective group \fBID\fR of
this process. (Not available in \fBsh\fR.)
.RE

.sp
.ne 2
.na
\fB\fB-h\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is a symbolic link.
.RE

.sp
.ne 2
.na
\fB\fB-k\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and has its sticky bit set.
.RE

.sp
.ne 2
.na
\fB\fB-L\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is a symbolic link.
.RE

.sp
.ne 2
.na
\fB\fB-n\fR \fIstring\fR\fR
.ad
.RS 28n
True if the length of \fIstring\fR is non-zero.
.RE

.sp
.ne 2
.na
\fB\fB-o\fR \fIoption\fR\fR
.ad
.RS 28n
True if option named \fIoption\fR is on. This option is not available in
\fBcsh\fR or \fBsh\fR.
.RE

.sp
.ne 2
.na
\fB\fB-O\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is owned by the effective user \fBID\fR of this
process. This option is not available in \fBsh\fR.
.RE

.sp
.ne 2
.na
\fB\fB-p\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR is a named pipe (\fBFIFO\fR).
.RE

.sp
.ne 2
.na
\fB\fB-r\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is readable.
.RE

.sp
.ne 2
.na
\fB\fB-s\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and has a size greater than zero.
.RE

.sp
.ne 2
.na
\fB\fB-S\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is a socket. This option is not available in
\fBsh\fR.
.RE

.sp
.ne 2
.na
\fB\fB-t\fR [\fIfile_descriptor\fR]\fR
.ad
.RS 28n
True if the file whose file descriptor number is \fIfile_descriptor\fR is open
and is associated with a terminal. If \fIfile_descriptor\fR is not specified,
\fB1\fR is used as a default value.
.RE

.sp
.ne 2
.na
\fB\fB-u\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and its set-user-ID flag is set.
.RE

.sp
.ne 2
.na
\fB\fB-w\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is writable. True indicates only that the write
flag is on. The \fIfile\fR is not writable on a read-only file system even if
this test indicates true.
.RE

.sp
.ne 2
.na
\fB\fB-x\fR \fIfile\fR\fR
.ad
.RS 28n
True if \fIfile\fR exists and is executable. True indicates only that the
execute flag is on. If \fIfile\fR is a directory, true indicates that
\fIfile\fR can be searched.
.RE

.sp
.ne 2
.na
\fB\fB-z\fR \fIstring\fR\fR
.ad
.RS 28n
True if the length of string \fIstring\fR is zero.
.RE

.sp
.ne 2
.na
\fB\fIfile1\fR \fB-nt\fR \fIfile2\fR\fR
.ad
.RS 28n
True if \fIfile1\fR exists and is newer than \fIfile2\fR. This option is not
available in \fBsh\fR.
.RE

.sp
.ne 2
.na
\fB\fIfile1\fR \fB-ot\fR \fIfile2\fR\fR
.ad
.RS 28n
True if \fIfile1\fR exists and is older than \fIfile2\fR. This option is not
available in \fBsh\fR.
.RE

.sp
.ne 2
.na
\fB\fIfile1\fR \fB-ef\fR \fIfile2\fR\fR
.ad
.RS 28n
True if \fIfile1\fR and \fIfile2\fR exist and refer to the same file. This
option is not available in \fBsh\fR.
.RE

.sp
.ne 2
.na
\fB\fIstring\fR\fR
.ad
.RS 28n
True if the string \fIstring\fR is not the null string.
.RE

.sp
.ne 2
.na
\fB\fIstring1\fR \fB=\fR \fIstring2\fR\fR
.ad
.RS 28n
True if the strings \fIstring1\fR and \fIstring2\fR are identical.
.RE

.sp
.ne 2
.na
\fB\fIstring1\fR \fB!=\fR \fIstring2\fR\fR
.ad
.RS 28n
True if the strings \fIstring1\fR and \fIstring2\fR are not identical.
.RE

.sp
.ne 2
.na
\fB\fIn1\fR \fB-eq\fR \fIn2\fR\fR
.ad
.RS 28n
True if the numbers \fIn1\fR and \fIn2\fR are algebraically equal. A number may
be integer, floating point or floating-point constant (such as [+/-]Inf,
[+/-]NaN) in any format specified by C99/XPG6/SUS.
.RE

.sp
.ne 2
.na
\fB\fIn1\fR \fB-ne\fR \fIn2\fR\fR
.ad
.RS 28n
True if the numbers \fIn1\fR and \fIn2\fR are not algebraically equal. A number
may be integer, floating point or floating-point constant (such as [+/-]Inf,
[+/-]NaN) in any format specified by C99/XPG6/SUS.
.RE

.sp
.ne 2
.na
\fB\fIn1\fR \fB-gt\fR \fIn2\fR\fR
.ad
.RS 28n
True if the number \fIn1\fR is algebraically greater than the number \fIn2\fR.
A number may be integer, floating point or floating-point constant (such as
[+/-]Inf, [+/-]NaN) in any format specified by C99/XPG6/SUS.
.RE

.sp
.ne 2
.na
\fB\fIn1\fR \fB-ge\fR \fIn2\fR\fR
.ad
.RS 28n
True if the number \fIn1\fR is algebraically greater than or equal to the
number \fIn2\fR. A number may be integer, floating point or floating-point
constant (such as [+/-]Inf, [+/-]NaN) in any format specified by C99/XPG6/SUS.
.RE

.sp
.ne 2
.na
\fB\fIn1\fR \fB-lt\fR \fIn2\fR\fR
.ad
.RS 28n
True if the number \fIn1\fR is algebraically less than the number \fIn2\fR. A
number may be integer, floating point or floating-point constant (such as
[+/-]Inf, [+/-]NaN) in any format specified by C99/XPG6/SUS.
.RE

.sp
.ne 2
.na
\fB\fIn1\fR \fB-le\fR \fIn2\fR\fR
.ad
.RS 28n
True if the number \fIn1\fR is algebraically less than or equal to the number
\fIn2\fR. A number may be integer, floating point or floating-point constant
(such as [+/-]Inf, [+/-]NaN) in any format specified by C99/XPG6/SUS.
.RE

.sp
.ne 2
.na
\fB\fIcondition1\fR \fB-a\fR \fIcondition2\fR\fR
.ad
.RS 28n
True if both \fIcondition1\fR and \fIcondition2\fR are true. The \fB-a\fR
binary primary is left associative and has higher precedence than the \fB-o\fR
binary primary.
.RE

.sp
.ne 2
.na
\fB\fIcondition1\fR \fB-o\fR \fIcondition2\fR\fR
.ad
.RS 28n
True if either \fIcondition1\fR or \fIcondition2\fR is true. The \fB-o\fR
binary primary is left associative.
.RE

.sp
.LP
These primaries can be combined with the following operators:
.sp
.ne 2
.na
\fB\fB!\fR \fIcondition\fR\fR
.ad
.RS 17n
True if \fIcondition\fR is false.
.RE

.sp
.ne 2
.na
\fB( \fIcondition\fR )\fR
.ad
.RS 17n
True if condition is true. The parentheses ( ) can be used to alter the normal
precedence and associativity. The parentheses are meaningful to the shell and,
therefore, must be quoted.
.RE

.sp
.LP
The algorithm for determining the precedence of the operators and the return
value that is generated is based on the number of arguments presented to
\fBtest\fR. (However, when using the \fB[...]\fR form, the right-bracket final
argument is not counted in this algorithm.)
.sp
.LP
In the following list, \fB$1\fR, \fB$2\fR, \fB$3\fR and \fB$4\fR represent the
arguments presented to \fBtest\fR as a \fIcondition\fR, \fIcondition1\fR, or
\fIcondition2\fR.
.sp
.ne 2
.na
\fB\fI0 arguments:\fR\fR
.ad
.RS 16n
Exit false (1).
.RE

.sp
.ne 2
.na
\fB\fI1 argument:\fR\fR
.ad
.RS 16n
Exit true (0) if \fB$1\fR is not null. Otherwise, exit false.
.RE

.sp
.ne 2
.na
\fB\fI2 arguments:\fR\fR
.ad
.RS 16n
.RS +4
.TP
.ie t \(bu
.el o
If \fB$1\fR is \fB!\fR, exit true if \fB$2\fR is null, false if \fB$2\fR is not
null.
.RE
.RS +4
.TP
.ie t \(bu
.el o
If \fB$1\fR is a unary primary, exit true if the unary test is true, false if
the unary test is false.
.RE
.RS +4
.TP
.ie t \(bu
.el o
Otherwise, produce unspecified results.
.RE
.RE

.sp
.ne 2
.na
\fB\fI3 arguments:\fR\fR
.ad
.RS 16n
.RS +4
.TP
.ie t \(bu
.el o
If \fB$2\fR is a binary primary, perform the binary test of \fB$1\fR and
\fB$3\fR.
.RE
.RS +4
.TP
.ie t \(bu
.el o
If \fB$1\fR is \fB!\fR, negate the two-argument test of \fB$2\fR and \fB$3\fR.
.RE
.RS +4
.TP
.ie t \(bu
.el o
Otherwise, produce unspecified results.
.RE
.RE

.sp
.ne 2
.na
\fB\fI4 arguments:\fR\fR
.ad
.RS 16n
.RS +4
.TP
.ie t \(bu
.el o
If \fB$1\fR is \fB!\fR, negate the three-argument test of \fB$2\fR, \fB$3\fR,
and \fB$4\fR.
.RE
.RS +4
.TP
.ie t \(bu
.el o
Otherwise, the results are unspecified.
.RE
.RE

.SH USAGE
.sp
.LP
Scripts should be careful when dealing with user-supplied input that could be
confused with primaries and operators. Unless the application writer knows all
the cases that produce input to the script, invocations like \fBtest "$1" -a
"$2"\fR should be written as \fBtest "$1" && test "$2"\fR to avoid problems if
a user supplied values such as \fB$1\fR set to \fB!\fR and \fB$2\fR set to the
null string. That is, in cases where maximal portability is of concern, replace
\fBtest expr1 -a expr2\fR with \fBtest expr1 && test expr2\fR, and replace
\fBtest expr1 -o expr2\fR with \fBtest expr1 || test expr2\fR. But notice that,
in \fBtest\fR, \fB-a\fR has \fBhigher\fR precedence than \fB-o\fR, while
\fB&&\fR and \fB||\fR have \fBequal\fR precedence in the shell.
.sp
.LP
Parentheses or braces can be used in the shell command language to effect
grouping.
.sp
.LP
Parentheses must be escaped when using \fBsh\fR. For example:
.sp
.in +2
.nf
test \e( expr1 -a expr2 \e) -o expr3
.fi
.in -2

.sp
.LP
This command is not always portable outside XSI-conformant systems. The
following form can be used instead:
.sp
.in +2
.nf
( test expr1 && test expr2 ) || test expr3
.fi
.in -2

.sp
.LP
The two commands:
.sp
.in +2
.nf
test "$1"
test ! "$1"
.fi
.in -2

.sp
.LP
could not be used reliably on some historical systems. Unexpected results would
occur if such a \fIstring\fR condition were used and \fB$1\fR expanded to
\fB!\fR, \fB(\fR, or a known unary primary. Better constructs are,
respectively,
.sp
.in +2
.nf
test -n "$1"
test -z "$1"
.fi
.in -2

.sp
.LP
Historical systems have also been unreliable given the common construct:
.sp
.in +2
.nf
test "$response" = "expected string"
.fi
.in -2

.sp
.LP
One of the following is a more reliable form:
.sp
.in +2
.nf
test "X$response" = "Xexpected string"
test "expected string" = "$response"
.fi
.in -2

.sp
.LP
The second form assumes that \fBexpected string\fR could not be confused with
any unary primary. If \fBexpected string\fR starts with \fB\(mi\fR, \fB(\fR,
\fB!\fR or even \fB=\fR, the first form should be used instead. Using the
preceding rules without the marked extensions, any of the three comparison
forms is reliable, given any input. (However, observe that the strings are
quoted in all cases.)
.sp
.LP
Because the string comparison binary primaries, \fB=\fR and \fB!=\fR, have a
higher precedence than any unary primary in the >4 argument case, unexpected
results can occur if arguments are not properly prepared. For example, in
.sp
.in +2
.nf
test -d $1 -o -d $2
.fi
.in -2

.sp
.LP
If \fB$1\fR evaluates to a possible directory name of \fB=\fR, the first three
arguments are considered a string comparison, which causes a syntax error when
the second \fB-d\fR is encountered. is encountered. One of the following forms
prevents this; the second is preferred:
.sp
.in +2
.nf
test \e( -d "$1" \e) -o \e( -d "$2" \e)
test -d "$1" || test -d "$2"
.fi
.in -2

.sp
.LP
Also in the >4 argument case:
.sp
.in +2
.nf
test "$1" = "bat" -a "$2" = "ball"
.fi
.in -2

.sp
.LP
Syntax errors occur if \fB$1\fR evaluates to \fB(\fR or \fB!\fR. One of the
following forms prevents this; the third is preferred:
.sp
.in +2
.nf
test "X$1" = "Xbat" -a "X$2" = "Xball"
test "$1" = "bat" && test "$2" = "ball"
test "X$1" = "Xbat" && test "X$2" = "Xball"
.fi
.in -2

.SH EXAMPLES
.sp
.LP
In the \fBif\fR command examples, three conditions are tested, and if all three
evaluate as true or successful, then their validities are written to the
screen. The three tests are:
.RS +4
.TP
.ie t \(bu
.el o
if a variable set to 1 is greater than 0,
.RE
.RS +4
.TP
.ie t \(bu
.el o
if a variable set to 2 is equal to 2, and
.RE
.RS +4
.TP
.ie t \(bu
.el o
if the word \fBroot\fR is included in the text file \fB/etc/passwd\fR.
.RE
.SS "/usr/bin/test"
.LP
\fBExample 1 \fRUsing /usr/bin/test
.sp
.LP
Perform a \fBmkdir\fR if a directory does not exist:

.sp
.in +2
.nf
test ! -d tempdir && mkdir tempdir
.fi
.in -2

.sp
.LP
Wait for a file to become non-readable:

.sp
.in +2
.nf
while test -r thefile
do
   sleep 30
done
echo'"thefile" is no longer readable'
.fi
.in -2

.sp
.LP
Perform a command if the argument is one of three strings (two variations),
using the open bracket version \fB[\fR of the \fBtest\fR command:

.sp
.in +2
.nf
if [ "$1" = "pear" ] || [ "$1" = "grape" ] || [ "$1" = "apple" ]
then
    command
fi
case "$1" in
    pear|grape|apple) command;;
esac
.fi
.in -2

.LP
\fBExample 2 \fRUsing /usr/bin/test for the -e option
.sp
.LP
If one really wants to use the \fB-e\fR option in \fBsh\fR, use
\fB/usr/bin/test\fR, as in the following:

.sp
.in +2
.nf
if [ ! -h $PKG_INSTALL_ROOT$rLink ] && /usr/bin/test -e
$PKG_INSTALL_ROOT/usr/bin/$rFile ; then
    ln -s $rFile $PKG_INSTALL_ROOT$rLink
fi
.fi
.in -2

.SS "The test built-in"
.sp
.LP
The two forms of the \fBtest\fR built-in follow the Bourne shell's \fBif\fR
example.
.LP
\fBExample 3 \fRUsing the sh built-in
.sp
.in +2
.nf
ZERO=0 ONE=1 TWO=2 ROOT=root

if  [ $ONE \fB-gt\fR $ZERO ]

[ $TWO \fB-eq\fR 2 ]

grep $ROOT  /etc/passwd >&1 > /dev/null  \fI# discard output\fR

then

    echo "$ONE is greater than 0, $TWO equals 2, and $ROOT is" \e
          "a user-name in the password file"

else

    echo "At least one of the three test conditions is false"
fi
.fi
.in -2

.LP
\fBExample 4 \fRUsing the test built-in
.sp
.LP
Examples of the \fBtest\fR built-in:

.sp
.in +2
.nf
test \(gagrep $ROOT /etc/passwd >&1 /dev/null\(ga   \fI# discard output\fR

echo $?    \fI# test for success\fR
[ \(gagrep nosuchname /etc/passwd >&1 /dev/null\(ga ]

echo $?    \fI# test for failure\fR
.fi
.in -2

.SS "csh"
.LP
\fBExample 5 \fRUsing the csh built-in
.sp
.in +2
.nf
@ ZERO = 0; @ ONE = 1; @ TWO = 2;  set ROOT = root
grep $ROOT  /etc/passwd >&1 /dev/null  \fI# discard output\fR
    \fI# $status must be tested for immediately following grep\fR
if ( "$status" == "0" && $ONE > $ZERO && $TWO == 2 ) then
       echo "$ONE is greater than 0, $TWO equals 2, and $ROOT is" \e
             "a user-name in the password file"
 endif
.fi
.in -2

.SS "ksh"
.LP
\fBExample 6 \fRUsing the ksh/ksh93 built-in
.sp
.in +2
.nf
ZERO=0 ONE=1 TWO=$((ONE+ONE)) ROOT=root
if  ((ONE > ZERO))            \fI#  arithmetical comparison\fR
 [[ $TWO = 2 ]]                \fI#  string comparison\fR
 [ \(gagrep $ROOT  /etc/passwd >&1 /dev/null\(ga ] \fI# discard output\fR
then
     echo "$ONE is greater than 0, $TWO equals 2, and $ROOT is" \e
             "a user-name in the password file"

else
     echo "At least one of the three test conditions is false"
fi
.fi
.in -2

.SH ENVIRONMENT VARIABLES
.sp
.LP
See \fBenviron\fR(7) for descriptions of the following environment variables
that affect the execution of \fBtest\fR: \fBLANG\fR, \fBLC_ALL\fR,
\fBLC_CTYPE\fR, \fBLC_MESSAGES\fR, and \fBNLSPATH\fR.
.SH EXIT STATUS
.sp
.LP
The following exit values are returned:
.sp
.ne 2
.na
\fB\fB0\fR\fR
.ad
.RS 6n
\fIcondition\fR evaluated to true.
.RE

.sp
.ne 2
.na
\fB\fB1\fR\fR
.ad
.RS 6n
\fIcondition\fR evaluated to false or \fIcondition\fR was missing.
.RE

.sp
.ne 2
.na
\fB\fB>1\fR\fR
.ad
.RS 6n
An error occurred.
.RE

.SH ATTRIBUTES
.sp
.LP
See \fBattributes\fR(7) for descriptions of the following attributes:
.SS "/usr/bin/test, csh, ksh, sh"
.sp

.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE	ATTRIBUTE VALUE
_
Interface Stability	Committed
_
Standard	See \fBstandards\fR(7).
.TE

.SS "ksh93"
.sp

.sp
.TS
box;
c | c
l | l .
ATTRIBUTE TYPE	ATTRIBUTE VALUE
_
Interface Stability	Uncommitted
.TE

.SH SEE ALSO
.sp
.LP
.BR csh (1),
.BR ksh (1),
.BR ksh93 (1),
.BR sh (1),
.BR test (1B),
.BR attributes (7),
.BR environ (7),
.BR largefile (7),
.BR standards (7)
.SH NOTES
.sp
.LP
The \fBnot\(mia\(midirectory\fR alternative to the \fB-f\fR option is a
transition aid for \fBBSD\fR applications and may not be supported in future
releases.
.SS "XPG4 \fBsh\fR, \fBksh\fR, \fBksh93\fR"
.sp
.LP
Use arithmetic expressions such as
.sp
.in +2
.nf
$(( x > 3.1 )) #
.fi
.in -2
.sp

.sp
.LP
instead of
.sp
.in +2
.nf
$ /usr/bin/test "$x" -gt 3.1 # )
.fi
.in -2
.sp

.sp
.LP
when comparing two floating-point variables or a constant and a floating-point
variable to prevent rounding errors (caused by the base16 to base10
transformation) to affect the result. Additionally the built-in arithmetic
support in XPG4 \fBsh\fR, \fBksh\fR and \fBksh93\fR is significantly faster
because it does not require the explicit transformation to strings for each
comparison.
